package com.zy.teacherSide.controller;

import com.zy.studentSide.entity.Student;
import com.zy.studentSide.entity.StudentTask;
import com.zy.studentSide.entity.StudentTaskFile;
import com.zy.studentSide.service.IStudentService;
import com.zy.studentSide.service.IStudentTaskFileService;
import com.zy.studentSide.service.IStudentTaskService;
import com.zy.teacherSide.entity.*;
import com.zy.teacherSide.entity.dto.StudentSubmitDTO;
import com.zy.teacherSide.entity.dto.TaskDTO;
import com.zy.teacherSide.entity.ov.CourseOV;
import com.zy.teacherSide.entity.ov.EnclosureId;
import com.zy.teacherSide.entity.ov.TaskOV;
import com.zy.teacherSide.service.*;
import com.zy.util.DateUtil;
import com.zy.util.R;
import com.zy.util.RandomNum;
import com.zy.util.ZipUtil;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @author 29787
 */
@RestController
public class TeacherTaskController {

    @Autowired
    private ITeacherTaskService iTeacherTaskService;

    @Autowired
    private IClassroomService iClassroomService;

    @Autowired
    private IStudentTaskService iStudentTaskService;

    @Autowired
    private ICourseService iCourseService;

    @Autowired
    private ITeacherEnclosureService iTeacherEnclosureService;

    @Autowired
    private ITeacherService iTeacherService;

    @Autowired
    private IStudentService iStudentService;

    @Autowired
    private IStudentTaskFileService iStudentTaskFileService;

    @Autowired
    private IStudentTaskAchievementService iStudentTaskAchievementService;

    EnclosureId ei = new EnclosureId();

    /**
     * 教师创建作业
     *
     * @param tov
     * @param teacherId
     * @return R
     */
    @PostMapping
    @RequestMapping(value = "/teacherCreateTask/{teacherId}")
    public R saveTeacherTask(@RequestBody TaskOV tov, @PathVariable Integer teacherId) {
        // 封装作业信息数据，存入数据库
        TeacherTask teacherTask = new TeacherTask();

        Integer taskId = RandomNum.getRandomID(6);
        Integer enclosureId = RandomNum.getRandomID(6);

        ei.setEnclosureId(enclosureId);

        teacherTask.setTaskSubmitNumber(0);
        teacherTask.setTaskId(taskId);
        teacherTask.setEnclosureId(enclosureId);
        teacherTask.setTeacherId(teacherId);
        teacherTask.setTaskName(tov.getTaskName());
        teacherTask.setTaskDescribe(tov.getTaskDescribe());
        teacherTask.setStartTime(tov.getStartTime());
        teacherTask.setEndTime(tov.getEndTime());

        Classroom classroom = iClassroomService.getClassroomByNameAndTeacherId(tov.getClassroomName(), teacherId);
        Course course = iCourseService.getCourseByCourseNameAndTeacherId(tov.getCourseName(), teacherId);

        teacherTask.setCourseId(course.getCourseId());
        teacherTask.setClassroomId(classroom.getClassroomId());
        // 存入数据库
        return new R(iTeacherTaskService.save(teacherTask));
    }

    /**
     * 接收教师发布作业时上传的附件信息
     *
     * @param file
     * @param request
     * @param teacherId
     * @return R
     * @throws Exception
     */
    @PostMapping
    @RequestMapping(value = "/teacherGetTaskEnclosure/{teacherId}")
    public R getTaskEnclosure(@RequestParam("enclosureFile") MultipartFile file, HttpServletRequest request,
                              @PathVariable Integer teacherId) throws Exception {

        TeacherEnclosure te = new TeacherEnclosure();

        // 获取文件原始名称
        String oldFlieName = file.getOriginalFilename();
        //获取文件后缀
        String extension = "." + FilenameUtils.getExtension(file.getOriginalFilename());
        //生成新的文件名称
        String newFileName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + UUID.randomUUID().toString().replace("-", "") + extension;
        //文件大小
        long size = file.getSize();
        //文件类型
        String type = file.getContentType();
        //目录
        String realPath = ResourceUtils.getURL("classpath:").getPath() + "static/teacher_enclosure";
        String dateDirPath = realPath + "/" + new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        File dateDir = new File(dateDirPath);
        if (!dateDir.exists()) dateDir.mkdirs();

        //文件上传
        file.transferTo(new File(dateDir, newFileName));

        //封装教师发布作业时附带的附件信息
        te.setUploadFilePath(dateDirPath);
        te.setTeacherId(teacherId);
        te.setEnclosureId(ei.getEnclosureId());
        te.setEnclosureName(newFileName);
        te.setEnclosureSize((int) size);
        te.setOriginalFileName(oldFlieName);
        te.setContentType(type);
        //获取当前时间
        String currentDate = DateUtil.getCurrentDate();
        te.setUploadTime(currentDate);
        // 存入数据库
        return new R(iTeacherEnclosureService.save(te));
    }

    /**
     * 教师获取所有作业信息
     *
     * @param teacherId
     * @return R
     */
    @PostMapping
    @RequestMapping(value = "/teacherGetAllTask/{teacherId}")
    public R getAllTask(@PathVariable Integer teacherId) throws ParseException {
        List<TaskDTO> allList = new ArrayList<TaskDTO>();
        // 根据老师id查询所有作业信息
        List<TeacherTask> list = iTeacherTaskService.list();
        for (TeacherTask task : list) {
            TaskDTO taskDTO = new TaskDTO();
            //查询当前教师姓名
            Teacher teacher = iTeacherService.getTeacherByTeacherId(teacherId);
            //查询当前班级名称
            Classroom classroom = iClassroomService.getClassroomByClassroomId(task.getClassroomId());
            //查询当前课程名称
            Course course = iCourseService.getAllCourseByCourseId(teacherId, task.getCourseId());
            // 查询当前附件名称
            TeacherEnclosure teacherEnclosure = iTeacherEnclosureService.getTeacherEnclosureById(teacherId, task.getEnclosureId());
            //封装TaskDTO数据
            taskDTO.setTaskSubmitNumber(task.getTaskSubmitNumber());
            taskDTO.setTeacherName(teacher.getTeacherName());
            taskDTO.setTaskName(task.getTaskName());
            taskDTO.setTeacherName(teacher.getTeacherName());
            taskDTO.setClassroomName(classroom.getClassroomName());
            taskDTO.setNumberPersonsDue(classroom.getClassroomPeopleNum());
            taskDTO.setCourseName(course.getCourseName());
            taskDTO.setStartTime(task.getStartTime());
            taskDTO.setEndTime(task.getEndTime());
            taskDTO.setTeacherId(teacher.getTeacherId());
            taskDTO.setEnclosureId(teacherEnclosure.getEnclosureId());
            taskDTO.setClassroomId(classroom.getClassroomId());
            taskDTO.setTaskId(task.getTaskId());
            taskDTO.setCourseId(course.getCourseId());

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            // 开始时间跟结束时间
            boolean b = DateUtil.comparisonDate(sdf.parse(task.getStartTime()), sdf.parse(task.getEndTime()));
            // 今天的时间
            Date today = new Date();
            if (DateUtil.comparisonDate(sdf.parse(task.getStartTime()), today)) {
                taskDTO.setStatus("作业未开始");
            } else if (DateUtil.comparisonDate(today, sdf.parse(task.getEndTime()))) {
                taskDTO.setStatus("作业已截止");
            } else {
                taskDTO.setStatus("作业正在进行");
            }
            taskDTO.setTaskDescribe(task.getTaskDescribe());
            if (teacherEnclosure == null) {
                taskDTO.setEnclosureName("该作业没有上传附件");
            } else {
                taskDTO.setEnclosureName(teacherEnclosure.getOriginalFileName());
            }
            allList.add(taskDTO);
        }
        return new R(true, allList);
    }

    /**
     * 教师删除班级
     *
     * @param taskDTO
     * @return R
     */
    @PostMapping
    @RequestMapping(value = "/teacherDeleteTask/{teacherId}")
    public R teacherDeleteTask(@RequestBody TaskDTO taskDTO, @PathVariable Integer teacherId) {

        // 删除作业记录
        Classroom classroom = iClassroomService.getClassroomByNameAndTeacherId(taskDTO.getClassroomName(), teacherId);
        Course course = iCourseService.getCourseByCourseNameAndTeacherId(taskDTO.getCourseName(), teacherId);
        TeacherTask tt = iTeacherTaskService.getTeacherTask(course.getCourseId(), teacherId, classroom.getClassroomId());

        // 删除附件记录
        TeacherEnclosure te = iTeacherEnclosureService.getTeacherEnclosureById(teacherId, tt.getEnclosureId());
        boolean b = false;
        if (te != null) {
            b = iTeacherEnclosureService.removeById(te.getId());
        } else {
            b = true;
        }
        return new R(iTeacherTaskService.removeById(tt.getId()) && b);

    }

    /**
     * 教师查看作业的提交情况
     *
     * @param taskDTO
     * @return R
     */
    @PostMapping
    @RequestMapping(value = "/teacherSeeTaskSubmit")
    public R teacherSeeTaskSubmit(@RequestBody TaskDTO taskDTO) {
        List<StudentTask> st_list = iStudentTaskService.getStudentTaskById(taskDTO.getClassroomId(), taskDTO.getTaskId(), taskDTO.getTeacherId(), taskDTO.getCourseId());
        List<StudentSubmitDTO> ssDTO_list = new ArrayList<StudentSubmitDTO>();
        for (StudentTask st : st_list) {
            StudentSubmitDTO ssDTO = new StudentSubmitDTO();

            // 获取成绩信息
            StudentTaskAchievement sta = iStudentTaskAchievementService.getStudentTaskAchievements(st.getCourseId(), st.getTaskId(), st.getTeacherId(), st.getClassroomId(), st.getStudentId());

            if (sta != null) {
                ssDTO.setAchievement(sta.getAchievement());
            } else {
                ssDTO.setAchievement(0);
            }
            Student s = iStudentService.getStudentByStudentId(st.getStudentId());

            ssDTO.setStudentName(s.getStudentName());
            ssDTO.setStudentNum(s.getStudentNum());
            ssDTO.setStudentId(s.getStudentId());

            ssDTO.setTaskId(st.getTaskId());
            ssDTO.setTeacherId(st.getTeacherId());
            ssDTO.setClassroomId(st.getClassroomId());
            ssDTO.setCourseId(st.getCourseId());
            ssDTO.setTaskId(st.getTaskId());

            StudentTaskFile stf = iStudentTaskFileService.getStudentTaskFileById(st.getTaskId(), st.getStudentId());
            ssDTO.setOriginalFileName(stf.getOriginalFileName());
            ssDTO.setUploadFileTime(stf.getUploadFileTime());
            ssDTO.setUploadFileId(stf.getUploadFileId());
            ssDTO_list.add(ssDTO);
        }
        return new R(true, ssDTO_list);
    }

    /**
     * 批量下载作业附件
     *
     * @param ssDTO
     * @return ResponseEntity<ByteArrayResource>
     * @throws Exception
     */
    @PostMapping
    @RequestMapping(value = "/teacherDownStudentFile")
    public ResponseEntity<ByteArrayResource> downloadFile(@RequestBody StudentSubmitDTO[] ssDTO) throws Exception {
        TeacherTask tt = iTeacherTaskService.getTeacherTaskByTaskId(ssDTO[0].getCourseId(), ssDTO[0].getTaskId(), ssDTO[0].getTeacherId(), ssDTO[0].getClassroomId());
        // 需要创建动态压缩目录
        String realPath = ResourceUtils.getURL("classpath:").getPath() + "static/compressed_directory";
        String path = realPath + "/" + tt.getTaskName();
        File pathDir = new File(path);
        if (!pathDir.exists()) pathDir.mkdirs();

        for (int j = 0; j < ssDTO.length; j++) {
            StudentTaskFile stf = iStudentTaskFileService.getStudentTaskFile(ssDTO[j].getTaskId(), ssDTO[j].getStudentId(), ssDTO[j].getUploadFileId());
            String realPath1 = ResourceUtils.getURL("classpath:").getPath() + "static/student_task";

            String filePath = realPath1 + "/" + stf.getUploadFilePath() + "/" + stf.getUploadFileName();

            ZipUtil.copy(new File(filePath.substring(1)), new File(pathDir + "/"));
        }

        String downPath = path + ".zip";
        FileOutputStream fos1 = new FileOutputStream(new File(downPath));
        ZipUtil.toZip(path.substring(1), fos1, true);
        File tempFile = new File(downPath.trim());
        String fName = tempFile.getName();
        String p = realPath + "/" + fName;

        // 3. 下载文件
        byte[] data = Files.readAllBytes(Paths.get(p.substring(1)));
        ByteArrayResource resource = new ByteArrayResource(data);

        // 删除文件
        delete(new File(realPath));

        return ResponseEntity.ok()
                .header("Content-disposition", "attachment;filename=" + URLEncoder.encode(fName, "UTF-8"))
                .contentType(MediaType.APPLICATION_OCTET_STREAM).contentLength(data.length)
                .body(resource);

    }

    /**
     * 删除文件夹
     *
     * @param file
     */
    public static void delete(File file) {
        if (!file.exists()) return;

        if (file.isFile() || file.list() == null) {
            file.delete();
        } else {
            File[] files = file.listFiles();
            for (File a : files) {
                delete(a);
            }
            file.delete();
        }

    }

    /**
     * 教师给学生打分
     *
     * @param ssDTO
     * @return R
     */
    @PostMapping
    @RequestMapping(value = "/teacherMarksForStudent")
    public R teacherMarksForStudent(@RequestBody StudentSubmitDTO[] ssDTO) {
        boolean b = false;
        boolean b1 = false;
        for (int i = 0; i < ssDTO.length; i++) {
            StudentTaskAchievement stat = iStudentTaskAchievementService.getStudentTaskAchievements(ssDTO[i].getCourseId(), ssDTO[i].getTaskId(), ssDTO[i].getTeacherId(), ssDTO[i].getClassroomId(), ssDTO[i].getStudentId());
            StudentTaskAchievement sta = new StudentTaskAchievement();
            if (stat == null) {
                // 表示第一次打分
                sta.setStudentId(ssDTO[i].getStudentId());
                sta.setAchievement(ssDTO[i].getAchievement());
                sta.setClassroomId(ssDTO[i].getClassroomId());
                sta.setCourseId(ssDTO[i].getCourseId());
                sta.setTaskId(ssDTO[i].getTaskId());
                sta.setTeacherId(ssDTO[i].getTeacherId());
                b = iStudentTaskAchievementService.save(sta);
            } else {
                // 表示已经打过分,现在为修改分数
                sta.setId(stat.getId());
                sta.setStudentId(stat.getStudentId());
                sta.setAchievement(ssDTO[i].getAchievement());
                sta.setClassroomId(stat.getClassroomId());
                sta.setCourseId(stat.getCourseId());
                sta.setTaskId(stat.getTaskId());
                sta.setTeacherId(stat.getTeacherId());
               b1 = iStudentTaskAchievementService.updateById(sta);
            }
        }
        return new R(b || b1);
    }

    /**
     * 根据教师id查询所有作业名称
     *
     * @param teacherId
     * @return R
     */
    @PostMapping
    @RequestMapping(value = "/getAllTaskNameByTeacherId/{teacherId}")
    public R getAllTaskNameByTeacherId(@PathVariable Integer teacherId) {
        List<TeacherTask> ttt = iTeacherTaskService.getTeacherTaskByTeacherId(teacherId);
        List<CourseOV> list = new ArrayList<CourseOV>();
        for (TeacherTask c : ttt) {
            CourseOV cov = new CourseOV();
            cov.setTaskName(c.getTaskName());
            list.add(cov);
        }
        return new R(true, list);
    }

}
